#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
修复依赖兼容性问题的脚本
主要解决NumPy二进制兼容性问题和数据库初始化失败问题
"""

import os
import subprocess
import sys
import json
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("fix_dependencies.log"),
        logging.StreamHandler()
    ]
)


def run_command(command, cwd=None):
    """执行命令并返回结果"""
    logging.info(f"执行命令: {command}")
    try:
        result = subprocess.run(
            command,
            shell=True,
            cwd=cwd,
            capture_output=True,
            text=True,
            timeout=300
        )
        if result.returncode == 0:
            logging.info(f"命令执行成功: {command}")
            return True, result.stdout
        else:
            logging.error(f"命令执行失败: {command}")
            logging.error(f"错误输出: {result.stderr}")
            return False, result.stderr
    except Exception as e:
        logging.error(f"执行命令时出错: {command}")
        logging.error(str(e))
        return False, str(e)


def update_requirements():
    """更新requirements.txt文件，修复NumPy版本问题"""
    req_path = os.path.join(os.path.dirname(__file__), "requirements.txt")
    
    # 读取当前requirements.txt
    if os.path.exists(req_path):
        with open(req_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        
        # 更新NumPy和相关依赖的版本
        updated_lines = []
        numpy_updated = False
        
        for line in lines:
            if line.strip().lower().startswith('numpy'):
                updated_lines.append('numpy==1.24.4\n')
                numpy_updated = True
            elif line.strip().lower().startswith('pandas'):
                updated_lines.append('pandas==2.0.3\n')
            elif line.strip().lower().startswith('sqlalchemy'):
                updated_lines.append('SQLAlchemy==2.0.23\n')
            else:
                updated_lines.append(line)
        
        # 如果没有NumPy，则添加
        if not numpy_updated:
            updated_lines.append('numpy==1.24.4\n')
        
        # 确保包含所有必要的依赖
        required_deps = [
            'Flask==2.3.3\n',
            'flask-cors==4.0.0\n',
            'redis==5.0.1\n',
            'celery==5.3.4\n',
            'requests==2.31.0\n',
            'python-dotenv==1.0.0\n',
            'gunicorn==21.2.0\n',
            'psutil==5.9.5\n',
            'pymongo==4.5.0\n',
            'pyyaml==6.0.1\n',
            'scikit-learn==1.3.0\n'
        ]
        
        for dep in required_deps:
            if dep not in updated_lines:
                updated_lines.append(dep)
        
        # 写回更新后的requirements.txt
        with open(req_path, 'w', encoding='utf-8') as f:
            f.writelines(updated_lines)
        
        logging.info(f"已更新 {req_path}")
    else:
        logging.warning(f"未找到 {req_path}")
        # 创建新的requirements.txt
        default_requirements = [
            'Flask==2.3.3\n',
            'flask-cors==4.0.0\n',
            'numpy==1.24.4\n',
            'pandas==2.0.3\n',
            'SQLAlchemy==2.0.23\n',
            'redis==5.0.1\n',
            'celery==5.3.4\n',
            'requests==2.31.0\n',
            'python-dotenv==1.0.0\n',
            'gunicorn==21.2.0\n',
            'psutil==5.9.5\n',
            'pymongo==4.5.0\n',
            'pyyaml==6.0.1\n',
            'scikit-learn==1.3.0\n'
        ]
        with open(req_path, 'w', encoding='utf-8') as f:
            f.writelines(default_requirements)
        logging.info(f"已创建新的 {req_path}")


def install_dependencies():
    """安装更新后的依赖"""
    # 先卸载可能有冲突的包
    logging.info("开始清理和重新安装依赖...")
    
    # 卸载冲突的NumPy和相关包
    run_command("pip uninstall -y numpy pandas SQLAlchemy")
    
    # 强制重新安装所有依赖
    success, output = run_command(
        "pip install --force-reinstall --no-cache-dir -r requirements.txt",
        cwd=os.path.dirname(__file__)
    )
    
    if success:
        logging.info("依赖安装成功")
    else:
        logging.error("依赖安装失败，尝试使用--ignore-installed选项")
        # 尝试忽略已安装的包进行强制安装
        success, output = run_command(
            "pip install --ignore-installed --force-reinstall -r requirements.txt",
            cwd=os.path.dirname(__file__)
        )
        if success:
            logging.info("依赖安装成功")
        else:
            logging.error("依赖安装仍然失败，请手动检查")


def check_database_connection():
    """检查数据库连接"""
    db_check_script = """
import os
import sys
sys.path.append('.')

from app import create_app
from app.models import db

try:
    app = create_app()
    with app.app_context():
        # 测试数据库连接
        db.create_all()
        print("数据库连接成功，所有表已创建")
except Exception as e:
    print(f"数据库连接失败: {str(e)}")
    sys.exit(1)
"""
    
    script_path = os.path.join(os.path.dirname(__file__), "check_db_temp.py")
    with open(script_path, 'w', encoding='utf-8') as f:
        f.write(db_check_script)
    
    success, output = run_command(f"python {script_path}")
    os.remove(script_path)
    
    return success


def main():
    """主函数"""
    logging.info("开始修复依赖兼容性问题...")
    
    # 更新requirements.txt
    update_requirements()
    
    # 安装依赖
    install_dependencies()
    
    # 检查数据库连接
    logging.info("检查数据库连接...")
    db_success = check_database_connection()
    
    if db_success:
        logging.info("所有修复完成，数据库连接正常！")
    else:
        logging.error("修复完成，但数据库连接仍有问题，请检查错误信息")
    
    logging.info("修复过程完成")


if __name__ == "__main__":
    main()